<script setup lang="ts">
import type { CustomDialogInstance } from '@/types'
import { useParamList, type Param } from './composable'
import Sortable from 'sortablejs'

const props = defineProps<{
  energyCode: string
  energyName: string
  checkedParams: { indicatorName: string, measuringPointNumber: string }[]
}>()
const emits = defineEmits<{
  (e: 'ok', v: Param[]): void
}>()
const dialogRef = ref<CustomDialogInstance>()
const sortable = ref<Sortable>()

const title = computed(() => {
  return `【${props.energyName}】参数设置`
})
const checked = ref<string[]>([])
const sortLists = ref<Param[]>([])
const sortListsRef = ref<HTMLElement | null>(null)

const {
  lists,
  loading,
  queryParamList,
} = useParamList()

function handleChangeChecked() {
  const checkedIds = unref(checked)
  const sortIds = unref(sortLists).map(item => item.id)

  sortLists.value = sortLists.value.filter(item => checkedIds.includes(item.id))
  for (const id of checkedIds) {
    if (!sortIds.includes(id)) {
      sortLists.value.push(unref(lists).find(item => item.id === id)!)
    }
  }
}

function getSortResult() {
  const elems = Array.from(sortListsRef.value?.querySelectorAll('[data-sort-id]') ?? [])
  const elemIds = elems.map(item => item.getAttribute('data-sort-id')!)
  const result = elemIds.reduce((acc, v) => {
    const target = unref(sortLists).find(item => item.id === v)
    target && (acc = acc.concat([target]))
    return acc
  }, [] as any)
  return result
}

async function validate() {
  return new Promise<boolean>((resolve) => {
    resolve(unref(sortLists).every(item => item.indicatorName.trim().length > 0))
  })
}
async function clickSave() {
  const isValid = await validate()
  if (!isValid) {
    ElMessage.error('请填写指标名称')
    return
  }
  const result = getSortResult()
  close()
  emits('ok', result)
}

async function onOpen() {
  await queryParamList(props.energyCode)
  await nextTick()

  const cc = (props.checkedParams || []).map(v => v.measuringPointNumber)
  const mm = unref(lists).filter(v => cc.includes(v.measuringPointNumber))
  // 回显已配置的参数
  checked.value = mm.map(v => v.id)
  sortLists.value = mm.map(v => ({
    id: v.id,
    indicatorName: (props.checkedParams || []).find(vv => vv.measuringPointNumber === v.measuringPointNumber)?.indicatorName ?? '',
    measuringPointNumber: v.measuringPointNumber,
  }))
}

function open() {
  sortLists.value = []
  checked.value = []
  sortListsRef.value = null
  dialogRef.value?.open()
}
function close() {
  dialogRef.value?.close()
}

watchEffect(() => {
  if (unref(sortLists).length > 0 && sortListsRef.value) {
    sortable.value = Sortable.create(sortListsRef.value, {
      ghostClass: 'ghost',
    })
  }
})

defineExpose({
  open,
  close,
})
</script>

<template>
  <CustomDialog
    ref="dialogRef"
    :title="title" width="740px" :no-max-height="true"
    class="reset parameter-setting-dialog"
    confirm-button-text="查询"
    @open="onOpen"
    @confirm="clickSave"
  >
    <div class="h-[400px] w-full flex">
      <div v-loading="loading" class="w-[220px] overflow-auto p-3">
        <ElCheckboxGroup v-if="lists.length > 0" v-model="checked" @change="handleChangeChecked">
          <ElCheckbox v-for="item in lists" :key="item.id" :value="item.id">
            {{ item.measuringPointNumber }}<span class="text-placeholder">（{{ item.indicatorName }}）</span>
          </ElCheckbox>
        </ElCheckboxGroup>
        <span v-else class="text-placeholder p-3">暂无参数</span>
      </div>
      <ElDivider direction="vertical" style="height: 100%;" />
      <div class="flex-1 overflow-auto p-3">
        <div v-if="sortLists.length > 0" ref="sortListsRef">
          <ElRow
            v-for="element in sortLists" :key="element.id" :gutter="20" class="cursor-move px-3 py-2"
            :data-sort-id="element.id"
          >
            <ElCol :span="9">
              <div class="h-full flex items-center">
                <span class="text-placeholder flex-shrink-0">测点编码：</span>
                <code class="break-all">{{ element.measuringPointNumber }}</code>
              </div>
            </ElCol>
            <ElCol :span="15">
              <div class="h-full flex items-center">
                <span class="text-placeholder flex-shrink-0">
                  指标名称：
                </span>
                <ElInput v-model.trim="element.indicatorName" size="small" />
              </div>
            </ElCol>
          </ElRow>
        </div>
        <template v-else>
          <TableEmpty text="请勾选左侧的参数" :image-size="100" />
        </template>
      </div>
    </div>
  </CustomDialog>
</template>

<style lang="scss">
.list-move, /* apply transition to moving elements */
.list-enter-active,
.list-leave-active {
  transition: all 0.5s ease;
}

.list-enter-from,
.list-leave-to {
  opacity: 0;
  transform: translateX(30px);
}

/* ensure leaving items are taken out of layout flow so that moving
   animations can be calculated correctly. */
.list-leave-active {
  position: absolute;
}
.parameter-setting-dialog  {
  .el-dialog__body{
    border-top: 1px solid var(--el-border-color-lighter);
    border-bottom: 1px solid var(--el-border-color-lighter);
  }
  .ghost {
    background: var(--el-bg-color-page);
    opacity: .6;
  }
}
</style>
